﻿using System;
using System.Collections.Generic;
using System.Deployment.Application;
using System.Drawing;
using System.IO;
using System.Management;
using System.Net;
using System.Reflection;
using System.Text.RegularExpressions;

namespace DevTools.Common.Components
{
    public static class GeneralUtility
    {
        /// <summary>
        /// 디렉토리에 있는 모든 어셈블리를 반환한다.
        /// </summary>
        /// <param name="directoryPath">조사할 디렉토리 경로. null 이면 Environment.CurrentDirectory 를 사용.</param>
        /// <returns></returns>
        public static List<Assembly> GetAllAssemblies(string directoryPath)
        {
            DirectoryInfo directory = new DirectoryInfo(directoryPath ?? Environment.CurrentDirectory);
            FileInfo[] exeFiles = directory.GetFiles("*.exe");
            FileInfo[] dllFiles = directory.GetFiles("*.dll");
            List<Assembly> assemblies = new List<Assembly>(exeFiles.Length + dllFiles.Length);

            for (int i = 0; i < exeFiles.Length; i++)
                assemblies.Add(Assembly.LoadFile(exeFiles[i].FullName));
            for (int i = 0; i < dllFiles.Length; i++)
                assemblies.Add(Assembly.LoadFile(dllFiles[i].FullName));

            return assemblies;
        }

        /// <summary>
        /// 유효한 URL인지를 체크한다.
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static bool IsValidUrl(string text)
        {
            return Regex.IsMatch(text, @"^((ht|f)tp(s?)\:\/\/|~/|/)?([\w]+:\w+@)?([a-zA-Z]{1}([\w\-]+\.)+([\w]{2,5}))(:[\d]{1,5})?((/?\w+/)+|/?)(\w+\.[\w]{3,4})?((\?\w+=\w+)?(&\w+=\w+)*)?");
        }

        /// <summary>
        /// 웹상의 이미지 파일을 읽어 Bitmap 객체로 반환한다.
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static Bitmap LoadImageFromUrl(string url)
        {
            HttpWebRequest request;
            HttpWebResponse response = null;
            Stream stream = null;
            Bitmap bitmap = null;

            try
            {
                request = (HttpWebRequest) WebRequest.Create(url);
                request.AllowWriteStreamBuffering = true;

                response = (HttpWebResponse) request.GetResponse();

                if ((stream = response.GetResponseStream()) != null)
                    bitmap = new Bitmap(stream);
            }
            catch
            {
                return null;
            }
            finally
            {
                if (stream != null)
                    stream.Close();

                if (response != null)
                    response.Close();
            }

            return (bitmap);
        }

        /// <summary>
        /// 웹상의 이미지 파일을 읽어 바이트 배열로 반환한다.
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static byte[] LoadImageBinaryFromUrl(string url)
        {
            Bitmap bitmap = LoadImageFromUrl(url);

            if (bitmap == null)
                return null;

            try
            {
                MemoryStream ms = new MemoryStream();
                bitmap.Save(ms, bitmap.RawFormat);
                ms.Close();

                return ms.ToArray();
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 네트워크가 연결된 상태인지를 검사한다.
        /// </summary>
        /// <param name="url">테스트 대상 주소. null 이면 www.naver.com 을 사용</param>
        /// <returns></returns>
        public static bool CheckNetworkConnection(string url)
        {
            try
            {
                Dns.GetHostEntry(url ?? "www.naver.com");
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 버전 정보를 얻는다. (클릭원스로 배포되었으면 게시 버전)
        /// </summary>
        /// <returns></returns>
        public static Version GetVersion()
        {
            return (ApplicationDeployment.IsNetworkDeployed) ? ApplicationDeployment.CurrentDeployment.CurrentVersion : Assembly.GetEntryAssembly().GetName().Version;
        }

        public static string GetVersionText()
        {
            Version version = GetVersion();

            return string.Format("{0}.{1}.{2}", version.Major, version.Minor, version.Build);
        }

        public static string GetMacAddress()
        {
            ManagementClass managementClass = new ManagementClass("Win32_NetworkAdapterConfiguration");
            ManagementObjectCollection managementObjectCollection = managementClass.GetInstances();

            string macAddress = String.Empty;

            foreach (ManagementObject managementObject in managementObjectCollection)
            {
                if (macAddress == String.Empty)
                    if ((bool) managementObject["IPEnabled"])
                        macAddress = managementObject["MacAddress"].ToString();

                managementObject.Dispose();
            }

            macAddress = macAddress.Replace(":", "");
            return macAddress;
        }

        public static string GetProcessorID()
        {
            const string query = "SELECT ProcessorId FROM Win32_Processor";
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
            ManagementObjectCollection collection = searcher.Get();

            string processorID = string.Empty;
            foreach (ManagementObject item in collection)
            {
                processorID = (string) item["ProcessorId"];
                break;
            }

            return processorID;
        }
    }
}